-
Notifications
You must be signed in to change notification settings - Fork 108
Elimination of the PickleIndex from Row Test Method Signature #938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
This works on simple example. CI failing; will look into test failures tomorrow. |
| lock (pickle.Tags) | ||
| { | ||
| var tag = pickle.Tags.FirstOrDefault(t => t.Name == tagName); | ||
| if (tag != null) | ||
| { | ||
| pickle.Tags.Remove(tag); | ||
| return i.ToString(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work with retries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not following; what type of retry are you considering as a potential problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a test runner decides to re-run the outline example test within the same execution process, the second run will not find the pickle index.
| var tagsList = tags ?? Enumerable.Empty<string>(); | ||
| var rowValuesList = rowValues ?? Enumerable.Empty<string>(); | ||
| var v = $"{featureName}|{scenarioOutlineName}|{string.Join("|", tagsList)}|{string.Join("|", rowValuesList)}"; | ||
| return v.GetHashCode(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HashCodes aren't likely to overlap but they are not unique.
Is this a problem here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed this is an MD5 hash.
|
The CI build and tests are passing on github. Has anyone come across something similar? |
gasparnagy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have done a first round of review, here are my comments.
I still need to think of the re-run problem that was mentioned here, but I will post about that separately.
Reqnroll/Formatters/ExecutionTracking/FeatureExecutionTracker.cs
Outdated
Show resolved
Hide resolved
| lock (pickle.Tags) | ||
| { | ||
| var tag = pickle.Tags.FirstOrDefault(t => t.Name == tagName); | ||
| if (tag != null) | ||
| { | ||
| pickle.Tags.Remove(tag); | ||
| return i.ToString(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a test runner decides to re-run the outline example test within the same execution process, the second run will not find the pickle index.
Reqnroll/FeatureInfo.cs
Outdated
| /// This property holds the cucumber messages at the feature level created by the test class generator; populated when the FeatureStartedEvent is fired. Used internally. | ||
| /// </summary> | ||
| internal IFeatureLevelCucumberMessages FeatureCucumberMessages { get; set; } | ||
| public IFeatureLevelCucumberMessages FeatureCucumberMessages { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have to make this public? It would be better if feature info would only expose things publicly that the users can/should work with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it now - it is used in the generated code. I would pass the entire FeatureInfo to GetPickleIndexFromTestRow, so that it can access the internal prop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted and modified code gen per suggestion.
…romRowTestMethodSignature
|
OK. I have an idea how to make this more robust and also support re-runs.
@clrudolphi does that make sense? |
I had not yet given retry semantics much thought for this PR yet. Now that I think about it, it will be a mess and not much that we can do about it.
Using a first-come, first-served approach to assigning PickleIDs to rows will result in unintuitive results in the latter two situations. I'll think about this a bit more. |
Sure, but please note that this only happens if the two examples are fully identical and you use such retry functionality. In that case you could anyway consider that the two examples are retries of each-other. I'm not saying that the behavior is correct, but the situation is so special, that the behavior can be "good enough". |
…ing the code gen to pass the FeatureInfo to the test row mapper.
…k which pickleIndex is given out to an executing test. TestRowPickleMapper is simplified and limited to hash computation and matching/removing the PickleTag from the pickle. Tracking of which pickleIndices have been used is movedto FeatureLevelCucumberMessages. Marker PickleTags are removed at startup (FeatureLevelCucumberMessages constructor). PickleIndices are assigned on a round-robin basis for a given rowHash.
|
Thanks for the suggestions and reassurance. |
…aving an "internal" public method on FeatureInfo
gasparnagy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is good now, but since this is a kind of breaking change (as we have seen), I would feel better to put this to v4. What do you think?
|
I'll take a final look at the last set of changes. But, yes, agreed this should wait until v4. |
|
I will try to take a look at a build and gather some experiences with it after X-mas. I am totally fine with v4. We rolled back to v2 and can continue work with this so far. Anyway Thank you a lot! |
|
@StarWars999123 I hope to have v4 in early 2026, but definitely in Q1. |
Yes, sure. I wanted to highlight anyway that I've made a bit of refactoring that you should double-check. I just forgot... 😎 |
…pe of the code that is being generated. Added Changelog entry.
|
I think this is ready for v4. |
I had a bit of the same feeling. But the good news is, that essentially we don't need the pickle index concept. I have made a prototype that simply uses the pickle ID everywhere. That makes the whole thing much more straightforward. I have dropped it finally, because there is a disadvantage: every time we generate the code-behind, a new ID will be included. But once people will move on the let the code-behind generated in the obj folder, no one will care and also the new up-to-date checking infra we have is not sensitive for this anymore. We just need to wait a bit until these things get a bit more mature. And the massive amount of tests we have is a quite good protection anyway until then. |
🤔 What's changed?
This is how we eliminate the pickleIndex parameter from the signature of generated row tests.
A hash is taken of FeatureName, ScenarioName, Example tags, and row values. This hash is inserted as a hidden tag on the pickle that is generated at compile time. These are stored as resources in the test assembly.
Generated test method is changed to calculate this hash at run-time, look for a matching pickle and use its index from the list of pickles. If a test has duplicate rows (and with the same example tags) we can't predict which matching pickle will get assigned at runtime, but I think that is acceptable as there is no discernable difference between these tests anyway.
Retries still work as pickle indices are assigned for a given row hash on a round-robin basis and can be repeated.
⚡️ What's your motivation?
Removes an internal implementation detail from being visible to test frameworks and other CI tools.
This addresses the concerns raised in issue #927
🏷️ What kind of change is this?
♻️ Anything particular you want feedback on?
📋 Checklist:
This text was originally taken from the template of the Cucumber project, then edited by hand. You can modify the template here.